package cn.demoncat.util.es.entity;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.elasticsearch.action.admin.indices.stats.IndexStats;
import org.elasticsearch.action.admin.indices.stats.IndicesStatsResponse;
import org.elasticsearch.cluster.health.ClusterIndexHealth;

import com.alibaba.fastjson.JSONObject;

import cn.demoncat.util.lang.JsonUtil;

/**
 * 索引信息
 * 
 * @author 延晓磊
 *
 * @since 2019年12月27日
 */
public class IndexInfo {

	// 名称
	private String name;
	// 状态： GREEN、YELLOW、RED
	private String status;

	// 分片数
	private Integer numberOfShards;
	// 副本数
	private Integer numberOfReplicas;
	// 活跃的分片(主分片+副本分片)
	private Integer activeShards;
	// 活跃的主分片
	private Integer activePrimaryShards;
	// 迁移中的分片
	private Integer relocatingShards;
	// 初始化中的分片
	private Integer initializingShards;
	// 未分配的分片
	private Integer unassignedShards;

	// 索引存储大小：byte
	private Long storeSize;
	// 索引内存大小：byte
	private Long memSize;
	// 文档数
	private Long docCount;
	// 删除的文档数
	private Long docDeleteCount;
	// 索引操作次数
	private Long indexCount;
	// 索引失败次数
	private Long indexFailCount;
	// 删除操作次数
	private Long deleteCount;
	// 查询操作次数
	private Long queryCount;
	// 查询操作时间（毫秒）
	private Long queryTime;
	// 滚动操作次数
	private Long scrollCount;
	// 滚动操作时间（毫秒）
	private Long scrollTime;
	// 建议操作次数
	private Long suggestCount;
	// 建议操作时间（毫秒）
	private Long suggestTime;

	// 主分片索引存储大小：byte
	private Long primaryStoreSize;
	// 主分片索引内存大小：byte
	private Long primaryMemSize;
	// 主分片文档数
	private Long primaryDocCount;
	// 主分片删除的文档数
	private Long primaryDocDeleteCount;
	// 主分片索引操作次数
	private Long primaryIndexCount;
	// 主分片索引操作次数
	private Long primaryIndexFailCount;
	// 主分片删除操作次数
	private Long primaryDeleteCount;
	// 主分片查询操作次数
	private Long primaryQueryCount;
	// 主分片查询操作时间（毫秒）
	private Long primaryQueryTime;
	// 主分片滚动操作次数
	private Long primaryScrollCount;
	// 主分片滚动操作时间（毫秒）
	private Long primaryScrollTime;
	// 主分片建议操作次数
	private Long primarySuggestCount;
	// 主分片建议操作时间（毫秒）
	private Long primarySuggestTime;

	/**
	 * 转换
	 * 
	 * @param response
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月27日
	 */
	public static IndexInfo parse(ClusterIndexHealth response) {
		IndexInfo index = new IndexInfo();
		// 索引名称
		index.setName(response.getIndex());
		// 索引状态
		index.setStatus(response.getStatus().name());
		// 分片
		index.setNumberOfShards(response.getNumberOfShards());
		index.setNumberOfReplicas(response.getNumberOfReplicas());
		index.setActiveShards(response.getActiveShards());
		index.setActivePrimaryShards(response.getActivePrimaryShards());
		index.setInitializingShards(response.getInitializingShards());
		index.setRelocatingShards(response.getRelocatingShards());
		index.setUnassignedShards(response.getUnassignedShards());
		return index;
	}

	/**
	 * 解析
	 * 
	 * @param response
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月27日
	 */
	public static List<IndexInfo> parse(IndicesStatsResponse response) {
		List<IndexInfo> indexes = new ArrayList<>();
		IndexInfo index;
		for (IndexStats item : response.getIndices().values()) {
			index = new IndexInfo();
			// 主分片+副本
			index.setName(item.getIndex());
			index.setStoreSize(item.getTotal().getStore().getSizeInBytes());
			index.setMemSize(item.getTotal().getTotalMemory().getBytes());
			index.setDocCount(item.getTotal().getDocs().getCount());
			index.setDocDeleteCount(item.getTotal().getDocs().getDeleted());
			index.setIndexCount(item.getTotal().getIndexing().getTotal().getIndexCount());
			index.setIndexFailCount(item.getTotal().getIndexing().getTotal().getIndexFailedCount());
			index.setDeleteCount(item.getTotal().getIndexing().getTotal().getDeleteCount());
			index.setQueryCount(item.getTotal().getSearch().getTotal().getQueryCount());
			index.setQueryTime(item.getTotal().getSearch().getTotal().getQueryTimeInMillis());
			index.setScrollCount(item.getTotal().getSearch().getTotal().getScrollCount());
			index.setScrollTime(item.getTotal().getSearch().getTotal().getScrollTimeInMillis());
			index.setSuggestCount(item.getTotal().getSearch().getTotal().getSuggestCount());
			index.setSuggestTime(item.getTotal().getSearch().getTotal().getSuggestTimeInMillis());
			// 主分片
			index.setPrimaryStoreSize(item.getPrimaries().getStore().getSizeInBytes());
			index.setPrimaryMemSize(item.getPrimaries().getTotalMemory().getBytes());
			index.setPrimaryDocCount(item.getPrimaries().getDocs().getCount());
			index.setPrimaryDocDeleteCount(item.getPrimaries().getDocs().getDeleted());
			index.setPrimaryIndexCount(item.getPrimaries().getIndexing().getTotal().getIndexCount());
			index.setPrimaryIndexFailCount(item.getPrimaries().getIndexing().getTotal().getIndexFailedCount());
			index.setPrimaryDeleteCount(item.getPrimaries().getIndexing().getTotal().getDeleteCount());
			index.setPrimaryQueryCount(item.getPrimaries().getSearch().getTotal().getQueryCount());
			index.setPrimaryQueryTime(item.getPrimaries().getSearch().getTotal().getQueryTimeInMillis());
			index.setPrimaryScrollCount(item.getPrimaries().getSearch().getTotal().getScrollCount());
			index.setPrimaryScrollTime(item.getPrimaries().getSearch().getTotal().getScrollTimeInMillis());
			index.setPrimarySuggestCount(item.getPrimaries().getSearch().getTotal().getSuggestCount());
			index.setPrimarySuggestTime(item.getPrimaries().getSearch().getTotal().getSuggestTimeInMillis());
			indexes.add(index);
		}
		return indexes;
	}

	/**
	 * 解析
	 * 
	 * @param response
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2020年09月06日
	 */
	public static List<IndexInfo> parse(String response) {
		JSONObject indices = JsonUtil.parseObject(response).getJSONObject("indices");
		JSONObject total;
		JSONObject primary;
		List<IndexInfo> list = new ArrayList<>();
		IndexInfo info;
		for (String name : indices.keySet()) {
			info = new IndexInfo();
			info.setName(name);
			// 总数
			total = indices.getJSONObject(name).getJSONObject("total");
			info.setStoreSize(total.getJSONObject("store").getLong("size_in_bytes"));
			info.setMemSize(total.getJSONObject("segments").getLong("memory_in_bytes"));
			info.setDocCount(total.getJSONObject("docs").getLong("count"));
			info.setDocDeleteCount(total.getJSONObject("docs").getLong("deleted"));
			info.setIndexCount(total.getJSONObject("indexing").getLong("index_total"));
			info.setIndexFailCount(total.getJSONObject("indexing").getLong("index_failed"));
			info.setDeleteCount(total.getJSONObject("indexing").getLong("delete_total"));
			info.setQueryCount(total.getJSONObject("search").getLong("query_total"));
			info.setQueryTime(total.getJSONObject("search").getLong("query_time_in_millis"));
			info.setScrollCount(total.getJSONObject("search").getLong("scroll_total"));
			info.setScrollTime(total.getJSONObject("search").getLong("scroll_time_in_millis"));
			info.setSuggestCount(total.getJSONObject("search").getLong("suggest_total"));
			info.setSuggestTime(total.getJSONObject("search").getLong("suggest_time_in_millis"));
			// 主分片
			primary = indices.getJSONObject(name).getJSONObject("primaries");
			info.setPrimaryStoreSize(primary.getJSONObject("store").getLong("size_in_bytes"));
			info.setPrimaryMemSize(primary.getJSONObject("segments").getLong("memory_in_bytes"));
			info.setPrimaryDocCount(primary.getJSONObject("docs").getLong("count"));
			info.setPrimaryDocDeleteCount(primary.getJSONObject("docs").getLong("deleted"));
			info.setPrimaryIndexCount(primary.getJSONObject("indexing").getLong("index_total"));
			info.setPrimaryIndexFailCount(primary.getJSONObject("indexing").getLong("index_failed"));
			info.setPrimaryDeleteCount(primary.getJSONObject("indexing").getLong("delete_total"));
			info.setPrimaryQueryCount(primary.getJSONObject("search").getLong("query_total"));
			info.setPrimaryQueryTime(primary.getJSONObject("search").getLong("query_time_in_millis"));
			info.setPrimaryScrollCount(primary.getJSONObject("search").getLong("scroll_total"));
			info.setPrimaryScrollTime(primary.getJSONObject("search").getLong("scroll_time_in_millis"));
			info.setPrimarySuggestCount(primary.getJSONObject("search").getLong("suggest_total"));
			info.setPrimarySuggestTime(primary.getJSONObject("search").getLong("suggest_time_in_millis"));
			list.add(info);
		}
		return list;
	}

	/**
	 * 合并
	 * 
	 * @param clusterIndexs
	 *            通过ClusterIndexHealth查询的索引信息
	 * @param indexes
	 *            通过IndicesStatsResponse查询的索引信息
	 * @return
	 * 
	 * @author 延晓磊
	 *
	 * @since 2019年12月27日
	 */
	public static List<IndexInfo> merge(List<IndexInfo> clusterIndexs, List<IndexInfo> indexes) {
		// 缓存
		Map<String, IndexInfo> map = new HashMap<>();
		for (IndexInfo item : clusterIndexs) {
			map.put(item.getName(), item);
		}
		// 合并
		IndexInfo clusert;
		for (IndexInfo index : indexes) {
			clusert = map.get(index.getName());
			if (clusert != null) {
				index.setStatus(clusert.getStatus());
				index.setActiveShards(clusert.getActiveShards());
				index.setActivePrimaryShards(clusert.getActivePrimaryShards());
				index.setNumberOfShards(clusert.getNumberOfShards());
				index.setNumberOfReplicas(clusert.getNumberOfReplicas());
				index.setInitializingShards(clusert.getInitializingShards());
				index.setRelocatingShards(clusert.getRelocatingShards());
				index.setUnassignedShards(clusert.getUnassignedShards());
			}
		}
		return indexes;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getActiveShards() {
		return activeShards;
	}

	public void setActiveShards(Integer activeShards) {
		this.activeShards = activeShards;
	}

	public Integer getActivePrimaryShards() {
		return activePrimaryShards;
	}

	public void setActivePrimaryShards(Integer activePrimaryShards) {
		this.activePrimaryShards = activePrimaryShards;
	}

	public Integer getNumberOfShards() {
		return numberOfShards;
	}

	public void setNumberOfShards(Integer numberOfShards) {
		this.numberOfShards = numberOfShards;
	}

	public Integer getNumberOfReplicas() {
		return numberOfReplicas;
	}

	public void setNumberOfReplicas(Integer numberOfReplicas) {
		this.numberOfReplicas = numberOfReplicas;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public Long getDeleteCount() {
		return deleteCount;
	}

	public void setDeleteCount(Long deleteCount) {
		this.deleteCount = deleteCount;
	}

	public Long getStoreSize() {
		return storeSize;
	}

	public void setStoreSize(Long storeSize) {
		this.storeSize = storeSize;
	}

	public Long getMemSize() {
		return memSize;
	}

	public void setMemSize(Long memSize) {
		this.memSize = memSize;
	}

	public Long getIndexCount() {
		return indexCount;
	}

	public void setIndexCount(Long indexCount) {
		this.indexCount = indexCount;
	}

	public Long getQueryCount() {
		return queryCount;
	}

	public void setQueryCount(Long queryCount) {
		this.queryCount = queryCount;
	}

	public Long getPrimaryStoreSize() {
		return primaryStoreSize;
	}

	public void setPrimaryStoreSize(Long primaryStoreSize) {
		this.primaryStoreSize = primaryStoreSize;
	}

	public Long getPrimaryMemSize() {
		return primaryMemSize;
	}

	public void setPrimaryMemSize(Long primaryMemSize) {
		this.primaryMemSize = primaryMemSize;
	}

	public Long getPrimaryIndexCount() {
		return primaryIndexCount;
	}

	public void setPrimaryIndexCount(Long primaryIndexCount) {
		this.primaryIndexCount = primaryIndexCount;
	}

	public Long getPrimaryDeleteCount() {
		return primaryDeleteCount;
	}

	public void setPrimaryDeleteCount(Long primaryDeleteCount) {
		this.primaryDeleteCount = primaryDeleteCount;
	}

	public Long getPrimaryQueryCount() {
		return primaryQueryCount;
	}

	public void setPrimaryQueryCount(Long primaryQueryCount) {
		this.primaryQueryCount = primaryQueryCount;
	}

	public Long getIndexFailCount() {
		return indexFailCount;
	}

	public void setIndexFailCount(Long indexFailCount) {
		this.indexFailCount = indexFailCount;
	}

	public Long getPrimaryIndexFailCount() {
		return primaryIndexFailCount;
	}

	public void setPrimaryIndexFailCount(Long primaryIndexFailCount) {
		this.primaryIndexFailCount = primaryIndexFailCount;
	}

	public Integer getInitializingShards() {
		return initializingShards;
	}

	public void setInitializingShards(Integer initializingShards) {
		this.initializingShards = initializingShards;
	}

	public Integer getRelocatingShards() {
		return relocatingShards;
	}

	public void setRelocatingShards(Integer relocatingShards) {
		this.relocatingShards = relocatingShards;
	}

	public Integer getUnassignedShards() {
		return unassignedShards;
	}

	public void setUnassignedShards(Integer unassignedShards) {
		this.unassignedShards = unassignedShards;
	}

	public Long getDocCount() {
		return docCount;
	}

	public void setDocCount(Long docCount) {
		this.docCount = docCount;
	}

	public Long getDocDeleteCount() {
		return docDeleteCount;
	}

	public void setDocDeleteCount(Long docDeleteCount) {
		this.docDeleteCount = docDeleteCount;
	}

	public Long getPrimaryDocCount() {
		return primaryDocCount;
	}

	public void setPrimaryDocCount(Long primaryDocCount) {
		this.primaryDocCount = primaryDocCount;
	}

	public Long getPrimaryDocDeleteCount() {
		return primaryDocDeleteCount;
	}

	public void setPrimaryDocDeleteCount(Long primaryDocDeleteCount) {
		this.primaryDocDeleteCount = primaryDocDeleteCount;
	}

	public Long getQueryTime() {
		return queryTime;
	}

	public void setQueryTime(Long queryTime) {
		this.queryTime = queryTime;
	}

	public Long getPrimaryQueryTime() {
		return primaryQueryTime;
	}

	public void setPrimaryQueryTime(Long primaryQueryTime) {
		this.primaryQueryTime = primaryQueryTime;
	}

	public Long getScrollCount() {
		return scrollCount;
	}

	public void setScrollCount(Long scrollCount) {
		this.scrollCount = scrollCount;
	}

	public Long getScrollTime() {
		return scrollTime;
	}

	public void setScrollTime(Long scrollTime) {
		this.scrollTime = scrollTime;
	}

	public Long getSuggestCount() {
		return suggestCount;
	}

	public void setSuggestCount(Long suggestCount) {
		this.suggestCount = suggestCount;
	}

	public Long getSuggestTime() {
		return suggestTime;
	}

	public void setSuggestTime(Long suggestTime) {
		this.suggestTime = suggestTime;
	}

	public Long getPrimaryScrollCount() {
		return primaryScrollCount;
	}

	public void setPrimaryScrollCount(Long primaryScrollCount) {
		this.primaryScrollCount = primaryScrollCount;
	}

	public Long getPrimaryScrollTime() {
		return primaryScrollTime;
	}

	public void setPrimaryScrollTime(Long primaryScrollTime) {
		this.primaryScrollTime = primaryScrollTime;
	}

	public Long getPrimarySuggestCount() {
		return primarySuggestCount;
	}

	public void setPrimarySuggestCount(Long primarySuggestCount) {
		this.primarySuggestCount = primarySuggestCount;
	}

	public Long getPrimarySuggestTime() {
		return primarySuggestTime;
	}

	public void setPrimarySuggestTime(Long primarySuggestTime) {
		this.primarySuggestTime = primarySuggestTime;
	}

}
